﻿using IRUM.TR;
using IRUM.Utils;
using IRUM.XingAPI;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace IRUM.UI
{
    public partial class FormDayMarket : Form
    {
        ThreadDayMarket thread = null;
        ThreadStart tStart = null;
        Thread threadDay = null;
        private SessionCtrl m_session = new SessionCtrl();

        public FormDayMarket()
        {
            InitializeComponent();
        }

        private void FormDayMarket_Load(object sender, EventArgs e)
        {
            LoginDialog dlg = new LoginDialog(m_session);

            if (dlg.ShowDialog() != System.Windows.Forms.DialogResult.OK)
            {
                this.Close();
            }

            thread = new ThreadDayMarket(this);

            //Thread 시작
            tStart = new ThreadStart(thread.Start);
            threadDay = new Thread(tStart);
            threadDay.Start();

            btnQuery.Enabled = false;
        }

        private void FormDayMarket_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (threadDay != null)
            {
                threadDay.Abort();
                threadDay = null;
                tStart = null;
                thread = null;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            bool isCompleted = true;

            if (pbFutureMin.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbFutureDay.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbOptionMin.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbOptionDay.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbMarketMin.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbMarketDay.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbInvestorTradeMin.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbInvestorTradeDay.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbTopStock.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbOpenYak.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbProgramTradeMin.Value < 100)
            {
                isCompleted = false;
            }

            if (isCompleted == true && pbProgramTradeDay.Value < 100)
            {
                isCompleted = false;
            }




            if (isCompleted == true)
            {
                timer1.Enabled = false;
                
                if (threadDay != null)
                {
                    threadDay.Abort();
                    threadDay = null;
                    tStart = null;
                    thread = null;

                    m_session.m_Session.Logout();
                    m_session.m_Session.DisconnectServer();
                }

                this.Close();
            }
        }

        private void btnQuery_Click(object sender, EventArgs e)
        {
            //Thread 시작
            tStart = new ThreadStart(thread.Start);
            threadDay = new Thread(tStart);
            threadDay.Start();
        }

        private delegate void ProgressDisplay(int value);

        public void SetProgressOptionMin(int value)
        {
            if (pbOptionMin.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressOptionMin);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbOptionMin.Value = value;
            }
        }

        public void SetProgressOptionDay(int value)
        {
            if (pbOptionDay.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressOptionDay);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbOptionDay.Value = value;
            }
        }

        public void SetProgressFutureMin(int value)
        {
            if (pbFutureMin.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressFutureMin);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbFutureMin.Value = value;
            }
        }

        public void SetProgressFutureDay(int value)
        {
            if (pbFutureDay.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressFutureDay);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbFutureDay.Value = value;
            }
        }

        public void SetProgressMarketMin(int value)
        {
            if (pbMarketMin.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressMarketMin);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbMarketMin.Value = value;
            }
        }

        public void SetProgressMarketDay(int value)
        {
            if (pbMarketDay.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressMarketDay);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbMarketDay.Value = value;
            }
        }

        public void SetProgressInvestorTradeMin(int value)
        {
            if (pbInvestorTradeMin.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressInvestorTradeMin);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbInvestorTradeMin.Value = value;
            }
        }

        public void SetProgressInvestorTradeDay(int value)
        {
            if (pbInvestorTradeDay.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressInvestorTradeDay);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbInvestorTradeDay.Value = value;
            }
        }

        public void SetProgressTopStock(int value)
        {
            if (pbTopStock.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressTopStock);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbTopStock.Value = value;
            }
        }

        public void SetProgressOpenYak(int value)
        {
            if (pbOpenYak.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressOpenYak);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbOpenYak.Value = value;
            }
        }

        public void SetProgressProgramTradeDay(int value)
        {
            if (pbProgramTradeDay.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressProgramTradeDay);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbProgramTradeDay.Value = value;
            }
        }

        public void SetProgressProgramTradeMin(int value)
        {
            if (pbProgramTradeMin.InvokeRequired)
            {
                ProgressDisplay printer = new ProgressDisplay(SetProgressProgramTradeMin);
                this.Invoke(printer, new object[] { value });
            }
            else
            {
                pbProgramTradeMin.Value = value;
            }
        }
    }

    /// <summary>
    /// 주간 장 정보수집 - 수급, 차트, 미결제약정, 프로그램매매, 해외지수, 업종
    /// 차트, 수급, 미결제약정의 경우 주간과 야간을 별도의 테이블에 저장해야 함.
    /// 차트
    ///       t8415 선물옵션 분봉
    ///       t8416 선물옵션 일봉
    ///       t8418 업종 분봉
    ///       t8419 업종 일봉
    ///       t8427 선물옵션 과거데이터 시간대별 조회 1999년 2월 이후의 데이터 조회 가능
    /// 수급
    ///       t1665 기간별 투자자
    ///       t1602 시간대별 투자자
    /// 미결제약정
    ///       t2421 선물/옵션 미결제약정 추이 (일/분)
    /// 시총상위
    ///       t1444 시가총액 상위(001:거래소, 301:코스닥) - 종가, 거래량, 등락, 등락율, 시가총액, 시장비중, 외국인지분율 등이 있음.
    /// </summary>
    class ThreadDayMarket
    {
        FormDayMarket form = null;

        int totalOptionCodeCount = 0;
        int totalFutureCodeCount = 0;
        int totalMarketCodeCount = 0;
        int totalInvestorTrade = 0;
        int totalOpenYakCount = 0;
        int totalTopStockCount = 0;
        int totalProgramTradeCount = 0;
       

        t8416 futureDaily = null;
        t8415 futureMinute = null;
        t8416 optionDaily = null;
        t8415 optionMinute = null;
        t8419 marketDaily = null;
        t8418 marketMinute = null;
        t1665 investorTradeDay = null;
        t1602 investorTradeMin = null;
        t2421 openyak = null;
        t1444 topStock = null;
        t1633 programTradeDaily = null;
        t1632 programTradeMinute = null;


        Queue<string> qCodeOptionMin = new Queue<string>();
        Queue<string> qCodeOptionDay = new Queue<string>();
        Queue<string> qCodeFutureMin = new Queue<string>();
        Queue<string> qCodeFutureDay = new Queue<string>();
        Queue<string> qCodeMarketDay = new Queue<string>();
        Queue<string> qCodeMarketMin = new Queue<string>();
        Queue<string> qInvestorTradeDay = new Queue<string>();
        Queue<string> qInvestorTradeMin = new Queue<string>();
        Queue<string> qCodeOpenYak = new Queue<string>();
        Queue<string> qTopStock = new Queue<string>();
        Queue<string> qProgramTradeDay = new Queue<string>();
        Queue<string> qProgramTradeMin = new Queue<string>();

        public ThreadDayMarket(FormDayMarket form)
        {
            this.form = form;

            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            DateTime lastDate = IRUM_Utils.GetLastTradingDateEvening(DateTime.Now);     //마지막 야간 거래일 - 전일정보를 가져오는 것


            //옵션 본월물 이후의 모든 종목코드 가져와서 큐에 넣어주기
            DateTime closingDateOfOption = IRUM_Utils.GetClosingDateOfOption(lastDate);         //마지막 야간 거래일 기준 옵션 만기일 - 전일기준으로 만기일을 가져와야 함.
            List<string> lstCodeOption = dc.ProdCodes.Where(p => p.kind.Equals("O") && Convert.ToInt32(p.expire) >= Convert.ToInt32(closingDateOfOption.ToString("yyyyMM"))).Select(p => p.shcode).ToList<string>();

            totalOptionCodeCount = lstCodeOption.Count;
            foreach (string code in lstCodeOption)
            {
                qCodeOptionMin.Enqueue(code);
                qCodeOptionDay.Enqueue(code);
            }


            //선물 본월물 이후의 모든 종목코드 가져와서 큐에 넣어주기
            DateTime closingDateOfFuture = IRUM_Utils.GetClosingDateOfFuture(lastDate);         //마지막 야간 거래일 기준 옵션 만기일 - 전일기준으로 만기일을 가져와야 함.
            List<string> lstCodeFuture = dc.ProdCodes.Where(p => p.kind.Equals("F") && Convert.ToInt32(p.expire) >= Convert.ToInt32(closingDateOfFuture.ToString("yyyyMM"))).Select(p => p.shcode).ToList<string>();

            totalFutureCodeCount = lstCodeFuture.Count;
            totalOpenYakCount = lstCodeFuture.Count;
            foreach (string code in lstCodeFuture)
            {
                qCodeFutureMin.Enqueue(code);
                qCodeFutureDay.Enqueue(code);
                qCodeOpenYak.Enqueue(code);
            }

            //업종코드 가져와서 큐에 넣어주기
            List<string> lstCodeMarket = dc.UpjongCodes.Select(p => p.shcode).ToList<string>();

            totalMarketCodeCount = lstCodeMarket.Count;
            foreach (string code in lstCodeMarket)
            {
                qCodeMarketDay.Enqueue(code);
                qCodeMarketMin.Enqueue(code);
            }

            //투자자매매추이 가져와서 큐에 넣어주기
            List<string> lstKindInvestorTrade = dc.InvestorTrades.Select(p => p.kind).Distinct().ToList<string>();

            totalInvestorTrade = lstKindInvestorTrade.Count;
            foreach (string kind in lstKindInvestorTrade)
            {
                qInvestorTradeDay.Enqueue(kind);
                qInvestorTradeMin.Enqueue(kind);
            }

            //시총상위종목조회 대상 업종
            qTopStock.Enqueue("001");   //코스피
            qTopStock.Enqueue("301");   //코스닥
            totalTopStockCount = qTopStock.Count;

            //프로그램매매추이
            qProgramTradeDay.Enqueue("K"); //코스피
            qProgramTradeDay.Enqueue("D"); //코스닥
            qProgramTradeMin.Enqueue("K"); //코스피
            qProgramTradeMin.Enqueue("D"); //코스닥

            totalProgramTradeCount = qProgramTradeDay.Count;
        }

        public void Start()
        {
            //선물 일봉조회 -> 옵션 일봉조회
            QueryFutureDaily();

            //나머지는  옵션 일봉 다 받은 후 조회한다.
        }


        #region 선물 차트조회
        /// <summary>
        /// 선물 분봉조회
        /// </summary>
        private void QueryFutureMinute()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19990201";
            string codeFuture = qCodeFutureMin.Dequeue();

            if (dc.ChartDataDays.Where(p => p.gubun.Equals("M") && p.shcode.Equals(codeFuture)).Count() > 0)
            {
                List<string> lstDate = dc.ChartDataDays.Where(p => p.gubun.Equals("M") && p.shcode.Equals(codeFuture)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            Thread.Sleep(1000);
            futureMinute = new t8415(codeFuture, lastDBDate);
            futureMinute.OnReceived += futureMinute_OnReceived;
            futureMinute.Request();
        }

        void futureMinute_OnReceived(object s, ChartDataArgs e)
        {
            foreach (ChartData c in e.RetData)
            {
                form.chartDataDayTableAdapter.sp_ChartDataDay_i(c.shcode, c.gubun, c.date, c.time, c.open, c.high, c.low, c.close, c.jdiff_vol, c.openyak);
            }
            e.RetData.Clear();

            form.SetProgressFutureMin(Convert.ToInt32(Convert.ToSingle(totalFutureCodeCount - qCodeFutureMin.Count) / totalFutureCodeCount * 100));

            if (qCodeFutureMin.Count > 0)
            {
                QueryFutureMinute();
            }
            else
            {
                chartDataDayBindingNavigatorSaveItem();
                QueryOptionMinute();
            }
        }

        /// <summary>
        /// 선물 일봉조회
        /// </summary>
        private void QueryFutureDaily()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19990201";
            string codeFuture = qCodeFutureDay.Dequeue();

            if (dc.ChartDataDays.Where(p => p.gubun.Equals("D") && p.shcode.Equals(codeFuture)).Count() > 0)
            {
                List<string> lstDate = dc.ChartDataDays.Where(p => p.gubun.Equals("D") && p.shcode.Equals(codeFuture)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            Thread.Sleep(1000);
            futureDaily = new t8416(codeFuture, lastDBDate);
            futureDaily.OnReceived += FutureDaily_OnReceived;
            futureDaily.Request();
        }

        void FutureDaily_OnReceived(object s, ChartDataArgs e)
        {
            foreach (ChartData c in e.RetData)
            {
                form.chartDataDayTableAdapter.sp_ChartDataDay_i(c.shcode, c.gubun, c.date, c.time, c.open, c.high, c.low, c.close, c.jdiff_vol, c.openyak);
            }
            e.RetData.Clear();

            form.SetProgressFutureDay(Convert.ToInt32(Convert.ToSingle(totalFutureCodeCount - qCodeFutureDay.Count) / totalFutureCodeCount * 100));

            if (qCodeFutureDay.Count > 0)
            {
                QueryFutureDaily();
            }
            else
            {
                chartDataDayBindingNavigatorSaveItem();
                QueryOptionDaily();
            }
        }
        #endregion


        #region 옵션차트 조회
        /// <summary>
        /// 옵션 분봉조회
        /// </summary>
        private void QueryOptionMinute()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19990201";
            string codeOption = qCodeOptionMin.Dequeue();

            if (dc.ChartDataDays.Where(p => p.gubun.Equals("M") && p.shcode.Equals(codeOption)).Count() > 0)
            {
                List<string> lstDate = dc.ChartDataDays.Where(p => p.gubun.Equals("M") && p.shcode.Equals(codeOption)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            Thread.Sleep(1000);
            optionMinute = new t8415(codeOption, lastDBDate);
            optionMinute.OnReceived += optionMinute_OnReceived;
            optionMinute.Request();
        }

        void optionMinute_OnReceived(object s, ChartDataArgs e)
        {
            foreach (ChartData c in e.RetData)
            {
                form.chartDataDayTableAdapter.sp_ChartDataDay_i(c.shcode, c.gubun, c.date, c.time, c.open, c.high, c.low, c.close, c.jdiff_vol, c.openyak);
            }
            e.RetData.Clear();

            form.SetProgressOptionMin(Convert.ToInt32(Convert.ToSingle(totalOptionCodeCount - qCodeOptionMin.Count) / totalOptionCodeCount * 100));

            if (qCodeOptionMin.Count > 0)
            {
                QueryOptionMinute();
            }
            else
            {
                chartDataDayBindingNavigatorSaveItem();
            }
        }

        /// <summary>
        /// 옵션 일봉조회
        /// </summary>
        private void QueryOptionDaily()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19990201";
            string codeOption = qCodeOptionDay.Dequeue();

            if (dc.ChartDataDays.Where(p => p.gubun.Equals("D") && p.shcode.Equals(codeOption)).Count() > 0)
            {
                List<string> lstDate = dc.ChartDataDays.Where(p => p.gubun.Equals("D") && p.shcode.Equals(codeOption)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            Thread.Sleep(1000);
            Debug.Print("[t8416], " + codeOption);
            optionDaily = new t8416(codeOption, lastDBDate);
            optionDaily.OnReceived += OptionDaily_OnReceived;
            optionDaily.Request();
        }

        void OptionDaily_OnReceived(object s, ChartDataArgs e)
        {
            foreach (ChartData c in e.RetData)
            {
                form.chartDataDayTableAdapter.sp_ChartDataDay_i(c.shcode, c.gubun, c.date, c.time, c.open, c.high, c.low, c.close, c.jdiff_vol, c.openyak);
            }
            e.RetData.Clear();

            form.SetProgressOptionDay(Convert.ToInt32(Convert.ToSingle(totalOptionCodeCount - qCodeOptionDay.Count) / totalOptionCodeCount * 100));

            if (qCodeOptionDay.Count > 0)
            {
                QueryOptionDaily();
            }
            else
            {
                chartDataDayBindingNavigatorSaveItem();

                //선물 분봉조회 -> 옵션 분봉조회
                QueryFutureMinute();

                //업종 일봉조회
                QueryMarketDaily();

                //업종 분봉조회
                QueryMarketMinute();

                //수급 일단위
                QueryInvestorTradeDaily();

                //수급 분단위
                QueryInvestorTradeMinute();

                //미결제약정
                if (qCodeOpenYak.Count > 0)
                {
                    codeOpenYak = qCodeOpenYak.Dequeue();
                    QueryOpenYak();
                }

                //시가총액 상위
                QueryTopStock();

                //기간별 프로그램 매매
                QueryProgramTradeDaily();

                //시간대별 프로그램 매매
                QueryProgramTradeMinute();
            }
        }
        #endregion


        #region 업종 차트조회
        /// <summary>
        /// 업종 분봉조회
        /// </summary>
        private void QueryMarketMinute()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19500101";
            string codeMarket = qCodeMarketMin.Dequeue();

            if (dc.ChartDataMarkets.Where(p => p.gubun.Equals("M") && p.shcode.Equals(codeMarket)).Count() > 0)
            {
                List<string> lstDate = dc.ChartDataMarkets.Where(p => p.gubun.Equals("M") && p.shcode.Equals(codeMarket)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            Thread.Sleep(1000);
            marketMinute = new t8418(codeMarket, lastDBDate);
            marketMinute.OnReceived += marketMinute_OnReceived;
            marketMinute.Request();
        }

        void marketMinute_OnReceived(object s, ChartDataArgs e)
        {
            foreach (ChartData c in e.RetData)
            {
                form.chartDataMarketTableAdapter.sp_ChartDataMarket_i(c.shcode, c.gubun, c.date, c.time, c.open, c.high, c.low, c.close, c.jdiff_vol, c.openyak);
            }
            e.RetData.Clear();

            form.SetProgressMarketMin(Convert.ToInt32(Convert.ToSingle(totalMarketCodeCount - qCodeMarketMin.Count) / totalMarketCodeCount * 100));

            if (qCodeMarketMin.Count > 0)
            {
                QueryMarketMinute();
            }
            else
            {
                chartDataMarketBindingNavigatorSaveItem();
            }
        }

        /// <summary>
        /// 업종 일봉조회
        /// </summary>
        private void QueryMarketDaily()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19500101";
            string codeMarket = qCodeMarketDay.Dequeue();

            if (dc.ChartDataMarkets.Where(p => p.gubun.Equals("D") && p.shcode.Equals(codeMarket)).Count() > 0)
            {
                List<string> lstDate = dc.ChartDataMarkets.Where(p => p.gubun.Equals("D") && p.shcode.Equals(codeMarket)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            Thread.Sleep(1000);
            marketDaily = new t8419(codeMarket, lastDBDate);
            marketDaily.OnReceived += marketDaily_OnReceived;
            marketDaily.Request();
        }

        void marketDaily_OnReceived(object s, ChartDataArgs e)
        {
            foreach (ChartData c in e.RetData)
            {
                form.chartDataMarketTableAdapter.sp_ChartDataMarket_i(c.shcode, c.gubun, c.date, c.time, c.open, c.high, c.low, c.close, c.jdiff_vol, c.openyak);
            }
            e.RetData.Clear();

            form.SetProgressMarketDay(Convert.ToInt32(Convert.ToSingle(totalMarketCodeCount - qCodeMarketDay.Count) / totalMarketCodeCount * 100));

            if (qCodeMarketDay.Count > 0)
            {
                QueryMarketDaily();
            }
            else
            {
                chartDataMarketBindingNavigatorSaveItem();
            }
        }
        #endregion


        #region 수급조회
        string kindInvestorTradeMin = string.Empty;
        
        /// <summary>
        /// 수급조회 - 분단위
        /// </summary>
        private void QueryInvestorTradeMinute()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19990201";
            string kind = qInvestorTradeMin.Dequeue();
            kindInvestorTradeMin = kind;

            if (dc.InvestorTrades.Where(p => p.gubun.Equals("M") && p.kind.Equals(kind)).Count() > 0)
            {
                List<string> lstDate = dc.InvestorTrades.Where(p => p.gubun.Equals("M") && p.kind.Equals(kind)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            investorTradeMin = new t1602(kind, lastDBDate);
            investorTradeMin.OnReceived += investorTradeMin_OnReceived;
            investorTradeMin.Request();
        }

        void investorTradeMin_OnReceived(object s, InvestorTradeArgs e)
        {
            foreach (TR.InvestorTrade it in e.RetData)
            {
                form.investorTradeTableAdapter.sp_InvestorTradeMin_i(kindInvestorTradeMin, it.date, it.gubun, it.time, it.native_sum, it.foreign_sum, it.organization_sum);
            }
            e.RetData.Clear();

            form.SetProgressInvestorTradeMin(Convert.ToInt32(Convert.ToSingle(totalInvestorTrade - qInvestorTradeMin.Count) / totalInvestorTrade * 100));

            if (qInvestorTradeMin.Count > 0)
            {
                QueryInvestorTradeMinute();
            }
            else
            {
                investorTradeBindingNavigatorSaveItem();
            }
        }

        string kindInvestorTradeDay = string.Empty;
        
        /// <summary>
        /// 수급조회 - 일단위
        /// </summary>
        private void QueryInvestorTradeDaily()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "19990201";
            string kind = qInvestorTradeDay.Dequeue();
            kindInvestorTradeDay = kind;

            if (dc.InvestorTrades.Where(p => p.gubun.Equals("D") && p.kind.Equals(kind)).Count() > 0)
            {
                List<string> lstDate = dc.InvestorTrades.Where(p => p.gubun.Equals("D") && p.kind.Equals(kind)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            investorTradeDay = new t1665(kind, lastDBDate);
            investorTradeDay.OnReceived += investorTradeDay_OnReceived;
            investorTradeDay.Request();
        }

        void investorTradeDay_OnReceived(object s, InvestorTradeArgs e)
        {
            foreach (TR.InvestorTrade it in e.RetData)
            {
                form.investorTradeTableAdapter.sp_InvestorTradeDay_i(kindInvestorTradeDay, it.date, it.gubun, it.time, it.native_buy, it.native_sell, it.native_sum, it.foreign_buy, it.foreign_sell, it.foreign_sum, it.organization_buy, it.organization_sell, it.organization_sum);
            }
            e.RetData.Clear();

            form.SetProgressInvestorTradeDay(Convert.ToInt32(Convert.ToSingle(totalInvestorTrade - qInvestorTradeDay.Count) / totalInvestorTrade * 100));

            if (qInvestorTradeDay.Count > 0)
            {
                QueryInvestorTradeDaily();
            }
            else
            {
                investorTradeBindingNavigatorSaveItem();
            }
        }
        #endregion


        #region 미결제약정
        string codeOpenYak = string.Empty;
        string gbnOpenYak = "M";

        /// <summary>
        /// 미결제약정
        /// </summary>
        private void QueryOpenYak()
        {
            Thread.Sleep(1000);
            openyak = new t2421(codeOpenYak, gbnOpenYak);
            openyak.OnReceived += openyak_OnReceived;
            openyak.Request();
        }

        void openyak_OnReceived(object s, OpenYakArgs e)
        {
            foreach (OpenYak oy in e.RetData)
            {
                form.openYakTableAdapter.sp_OpenYak_i(codeOpenYak, oy.gubun, oy.date, oy.time, oy.openopenyak, oy.highopenyak, oy.lowopenyak, oy.closeopenyak, oy.openupdn);
            }
            e.RetData.Clear();

            // 시간대별 데이터 조회 후 기간별 데이터 조회한 다음 다른 행사가 조회
            if (gbnOpenYak.Equals("M") == true)
            {
                gbnOpenYak = "D";
                QueryOpenYak();
            }
            else
            {
                form.SetProgressOpenYak(Convert.ToInt32(Convert.ToSingle(totalOpenYakCount - qCodeOpenYak.Count) / totalOpenYakCount * 100));

                if (qCodeOpenYak.Count > 0)
                {
                    codeOpenYak = qCodeOpenYak.Dequeue();
                    gbnOpenYak = "M";
                    QueryOpenYak();
                }
                else
                {
                    OpenYakBindingNavigatorSaveItem();
                }
            }
        }

        #endregion


        #region 시가총액 상위종목 조회
        /// <summary>
        /// 시가총액 상위종목 조회
        /// </summary>
        private void QueryTopStock()
        {
            Thread.Sleep(500);
            topStock = new t1444(qTopStock.Dequeue());
            topStock.OnReceived += topStock_OnReceived;
            topStock.Request();
        }

        void topStock_OnReceived(object s, TopStockArgs e)
        {
            foreach (TR.TopStock ts in e.RetData)
            {
                form.topStockTableAdapter.sp_TopStock_i(ts.date, ts.upcode, ts.idx, ts.shcode, ts.hname, ts.price, ts.change, ts.diff, ts.volume, ts.vol_rate, ts.total, ts.rate, ts.for_rate);
            }
            e.RetData.Clear();

            form.SetProgressTopStock(Convert.ToInt32(Convert.ToSingle(totalTopStockCount - qTopStock.Count) / totalTopStockCount * 100));

            if (qTopStock.Count > 0)
            {
                QueryTopStock();
            }
            else
            {
                topStockBindingNavigatorSaveItem();
            }
        }
        #endregion


        #region 프로그램 매매추이
        /// <summary>
        /// 기간별 프로그램 매매추이
        /// </summary>
        private void QueryProgramTradeDaily()
        {
            IRUMDataClassesDataContext dc = new IRUMDataClassesDataContext();
            string lastDBDate = "20010801"; 
            string codeMarket = qProgramTradeDay.Dequeue();

            if (dc.ProgramTrades.Where(p => p.gubun.Equals("D") && p.kind.Equals(codeMarket)).Count() > 0)
            {
                List<string> lstDate = dc.ProgramTrades.Where(p => p.gubun.Equals("D") && p.kind.Equals(codeMarket)).Select(p => p.date).ToList();
                string strMaxDate = lstDate.Max();
                DateTime maxDate = new DateTime(Convert.ToInt32(strMaxDate.Substring(0, 4)), Convert.ToInt32(strMaxDate.Substring(4, 2)), Convert.ToInt32(strMaxDate.Substring(6, 2)));
                lastDBDate = maxDate.AddDays(-5).ToString("yyyyMMdd");
            }

            if (codeMarket.Equals("D"))
            {
                lastDBDate = "20030113";
            }

            Thread.Sleep(500);
            programTradeDaily = new t1633(codeMarket, lastDBDate);
            programTradeDaily.OnReceived += programTrade_OnReceived;
            programTradeDaily.Request();
        }

        void programTrade_OnReceived(object s, ProgramTradeDataArgs e)
        {
            foreach (TR.ProgramTradeData pt in e.RetData)
            {
                form.programTradeTableAdapter.sp_ProgramTrade_i(pt.kind, pt.gubun, pt.date, pt.time, pt.jisu, pt.change, pt.totalSum, pt.totalBuy, pt.totalSell, pt.chaSum, pt.chaBuy, pt.chaSell, pt.bichaSum, pt.bichaBuy, pt.bichaSell, pt.volume);
            }
            e.RetData.Clear();

            form.SetProgressProgramTradeDay(Convert.ToInt32(Convert.ToSingle(totalProgramTradeCount - qProgramTradeDay.Count) / totalProgramTradeCount * 100));

            if (qProgramTradeDay.Count > 0)
            {
                QueryProgramTradeDaily();
            }
            else
            {
                programTradeBindingNavigatorSaveItem();
            }
        }
        
        /// <summary>
        /// 시간대별 프로그램 매매추이
        /// </summary>
        private void QueryProgramTradeMinute()
        {
            string codeMarket = qProgramTradeMin.Dequeue();

            Thread.Sleep(500);
            programTradeMinute = new t1632(codeMarket);
            programTradeMinute.OnReceived += programTradeMinute_OnReceived;
            programTradeMinute.Request();
        }

        void programTradeMinute_OnReceived(object s, ProgramTradeDataArgs e)
        {
            foreach (TR.ProgramTradeData pt in e.RetData)
            {
                form.programTradeTableAdapter.sp_ProgramTrade_i(pt.kind, pt.gubun, pt.date, pt.time, pt.jisu, pt.change, pt.totalSum, pt.totalBuy, pt.totalSell, pt.chaSum, pt.chaBuy, pt.chaSell, pt.bichaSum, pt.bichaBuy, pt.bichaSell, pt.volume);
            }
            e.RetData.Clear();

            form.SetProgressProgramTradeMin(Convert.ToInt32(Convert.ToSingle(totalProgramTradeCount - qProgramTradeMin.Count) / totalProgramTradeCount * 100));

            if (qProgramTradeMin.Count > 0)
            {
                QueryProgramTradeMinute();
            }
            else
            {
                programTradeBindingNavigatorSaveItem();
            }
        }
        #endregion



        #region DB 반영
        /// <summary>
        /// 선물옵션차트데이터 저장
        /// </summary>
        private void chartDataDayBindingNavigatorSaveItem()
        {
            form.chartDataDayBindingSource.EndEdit();
            form.tableAdapterManager.UpdateAll(form.iRUMDataSet);
        }

        /// <summary>
        /// 수급데이터 저장
        /// </summary>
        private void investorTradeBindingNavigatorSaveItem()
        {
            form.investorTradeBindingSource.EndEdit();
            form.tableAdapterManager.UpdateAll(form.iRUMDataSet);
        }

        /// <summary>
        /// 미결제약정데이터 저장
        /// </summary>
        private void OpenYakBindingNavigatorSaveItem()
        {
            form.openYakBindingSource.EndEdit();
            form.tableAdapterManager.UpdateAll(form.iRUMDataSet);
        }

        /// <summary>
        /// 업종차트데이터 저장
        /// </summary>
        private void chartDataMarketBindingNavigatorSaveItem()
        {
            form.chartDataMarketBindingSource.EndEdit();
            form.tableAdapterManager.UpdateAll(form.iRUMDataSet);
        }

        /// <summary>
        /// 시가총액상위데이터 저장
        /// </summary>
        private void topStockBindingNavigatorSaveItem()
        {
            form.topStockBindingSource.EndEdit();
            form.tableAdapterManager.UpdateAll(form.iRUMDataSet);
        }

        /// <summary>
        /// 프로그램매매추이 저장
        /// </summary>
        private void programTradeBindingNavigatorSaveItem()
        {
            form.programTradeBindingSource.EndEdit();
            form.tableAdapterManager.UpdateAll(form.iRUMDataSet);
        }
        #endregion
    }
}
